﻿using System;
using System.Windows.Input;
using WinRTFramework.Common;
using WinRTFramework.FrameworkConfiguration;
using WinRTFramework.Interfaces.Navigation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;

namespace WinRTFramework.FrameworkCore.Services
{
    internal class NavigationService : INavigationService
    {
        private readonly Frame rootFrame;
        private readonly IViewViewModelMapper viewProvider;

        public ICommand GoBackCommand 
        { 
            get; 
            private set; 
        }

        public ICommand GoForwardCommand
        {
            get;
            private set;
        }

        public ICommand GoHomeCommand
        {
            get;
            private set;
        }

        public NavigationService(Frame rootFrame, IViewViewModelMapper viewProvider)
        {
            this.rootFrame = rootFrame;
            this.viewProvider = viewProvider;

            this.GoBackCommand = new DelegateCommand(() => { this.rootFrame.GoBack(); }, () => { return this.rootFrame.CanGoBack; });
            this.GoForwardCommand = new DelegateCommand(() => { this.rootFrame.GoForward(); }, () => { return this.rootFrame.CanGoForward; });
            this.GoHomeCommand = new DelegateCommand(() => { while (this.rootFrame.CanGoBack) this.rootFrame.GoBack(); }, () => { return this.rootFrame.CanGoBack; });
        }

        public Type CurrentViewModelType
        {
            get
            {
                if (this.rootFrame.Content != null && this.rootFrame.Content is FrameworkElement)
                {
                    var viewModel = (this.rootFrame.Content as FrameworkElement).DataContext;
                    if (viewModel != null)
                    {
                        return viewModel.GetType();
                    }
                }
                return null;
            }
        }

        public bool Navigate<TViewModelType>()
        {
            return Navigate<TViewModelType>(null);
        }

        public bool Navigate<TViewModelType>(object navigationParameter)
        {
            var viewType = viewProvider.GetViewTypeForViewModelType(typeof(TViewModelType), navigationParameter);
            return rootFrame.Navigate(viewType, navigationParameter);
        }

        public bool Navigate(Type vmType)
        {
            return this.rootFrame.Navigate(vmType);
        }

        public bool Navigate(Type vmType, object navigationParameter)
        {
            return this.rootFrame.Navigate(vmType, navigationParameter);
        }
    }
}
